﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Diagnostics;
using System.Drawing;
using System.IO;
using System.Linq;
using Google.GData.Photos;

namespace PicasaWebAlbumsDownloader
{
    public class Controller
    {
        private readonly PicasaService service;
        private readonly IView view;
        public event EventHandler<CancelEventArgs> DownloadProgress;

        public Controller(IView view)
        {
            this.view = view;
            service = new PicasaService(view.AppName);
        }

        public Dictionary<PicasaEntry, int> RetrieveAlbumList()
        {
            var result = new Dictionary<PicasaEntry, int>();
            string uri = PicasaQuery.CreatePicasaUri(view.UserName);
            var query = new AlbumQuery(uri);
            PicasaFeed feed = service.Query(query);

            foreach (PicasaEntry entry in feed.Entries)
            {
                int numPhotos = int.Parse(entry.GetPhotoExtensionValue(GPhotoNameTable.NumPhotos));
                result.Add(entry, numPhotos);
            }

            return result;
        }

        public void DownloadSelectedAlbums()
        {
            if (string.IsNullOrEmpty(view.OutputDir) || !Directory.Exists(view.OutputDir))
            {
                throw new InvalidDirException(view.OutputDir);
            }
            Dictionary<PicasaEntry, int> albums = view.SelectedAlbums;
            int total = albums.Sum(x => x.Value);
            int current = 0;
            foreach (var album in albums)
            {
                view.Output.AppendLine(string.Format("Downloding '{0}'...", album.Key.Title.Text));
                try
                {
                    string albumDir = Path.Combine(view.OutputDir, album.Key.Title.Text.FixFileName());
                    DirectoryInfo directory = Directory.CreateDirectory(albumDir);

                    string uri = album.Key.FeedUri;
                    var query = new PhotoQuery(uri);

                    if (view.UseOriginalPhotoSize)
                    {
                        query.BaseAddress += "?imgmax=d";
                    }

                    PicasaFeed feed = service.Query(query);

                    foreach (PicasaEntry photo in feed.Entries)
                    {
                        var handler = DownloadProgress;
                        if (handler != null)
                        {
                            var cancelEventArgs = new CancelEventArgs(false);
                            handler(this, cancelEventArgs);
                            if (cancelEventArgs.Cancel)
                            {
                                view.Output.AppendLine("Downloading has been canceled.");
                                return;
                            }
                        }
                        current++;
                        view.Progress.ProgressValue = current*100/total;

                        string url = photo.Content.AbsoluteUri;
                        Stream stream = service.Query(new Uri(url));

                        using (Stream file = File.OpenWrite(Path.Combine(directory.FullName, photo.Title.Text.FixFileName())))
                        {
                            stream.CopyTo(file);
                        }
                    }
                } catch (Exception ex)
                {
                    view.Output.AppendLine(string.Format("Error: {0}", ex.Message));
                }
            }
        }

        public Bitmap GetSelectedAlbumThumbnail()
        {
            if (view.SelectedAlbum == null)
            {
                throw new InvalidAlbumException("No selected albums found.");
            }
            if (view.SelectedAlbum.Media == null
                || view.SelectedAlbum.Media.Thumbnails == null
                || view.SelectedAlbum.Media.Thumbnails.Count == 0
                )
            {
                throw new InvalidAlbumException(string.Format("No thumbnails found for the album '{0}'.", view.SelectedAlbum.Title.Text));
            }
            string url = view.SelectedAlbum.Media.Thumbnails[0].Url;
            using (var stream = service.Query(new Uri(url)))
            {
                return new Bitmap(stream);
            }
        }

        public string GetSelectedAlbumUri()
        {
            if (view.SelectedAlbum == null)
            {
                throw new InvalidAlbumException("No selected albums found.");
            }
            if (view.SelectedAlbum.AlternateUri == null
                )
            {
                throw new InvalidAlbumException(string.Format("No uri found for the album '{0}'.", view.SelectedAlbum.Title.Text));
            }
            var url = view.SelectedAlbum.AlternateUri.Content;
            return url;
        }

        public void WebOpenSelectedAlbum()
        {
            var uri = GetSelectedAlbumUri();
            if (uri != null)
            {
                var process = new Process();
                process.StartInfo = new ProcessStartInfo(uri);
                process.Start();
            }
        }
    }
}